#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2007 Denis Kürov
# Licensed under the GNU General Public License, version 3.
# See the file http://www.gnu.org/copyleft/gpl.txt.

from django import newforms as forms

from fireutil import FireUtils

#python modules
import re
import string

single_ip='(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}'
my_ip=re.compile(r'(^%s$)|(^%s-%s$)|(^%s/\d{1,2}$)'%(single_ip,single_ip,single_ip,single_ip))
    
class IpTableForm(forms.RegexField):
    """ A field for that project to be appropriate
    That one is also old"""
    
    def __init__(self, max_length=None, min_length=None,*args, **kwargs):
        """ The constructor"""
        super(IpTableForm,self).__init__(my_ip, max_length, min_length, 
                                         error_message="Girilen Ip Uygun Degil", *args, **kwargs)
        
    
    def clean(self,value):
        """ The validation process if occurrs"""
        
        if not value:
            raise forms.ValidationError("Bir ip degeri girmeniz gerekir!")
        
        value=value.strip()
        value=super(IpTableForm,self).clean(value)
        
        if not value:
            raise forms.ValidationError("Ip uygun degil")
        
        if string.find(value,'/')!=-1:
            values=value.split('/')
            #print values
            if not int(values[1])>7 and int(values[1])<32:
                raise forms.ValidationError("Subnet degeri uygun degil")
            
        
        if string.find(value,'-')!=-1:
            values=value.split('-')
            
            #the ip thing is not very good lets check it again
            kucuk=values[0].strip().split('.')
            buyuk=values[1].strip().split('.')
            
            print kucuk
            print buyuk
            
            if len(kucuk)!=len(buyuk):
                raise forms.ValidationError("Ip araligi uygun degil")
                
            for ip in kucuk :
                if int(ip)>int(buyuk[kucuk.index(ip)]):
                    raise forms.ValidationError("Ip araligi uygun degil")
            
            if int(kucuk[len(kucuk)-1])<= int(buyuk[len(buyuk)-1]):
                raise forms.ValidationError("Ip araligi uygun degil")
            
    
        return value #end of the validation
    



################################################################################################################
class PortField(forms.Field):
    """ A field for iptables port that are needed
    That one is old not used anymore for backup purpose is here"""
    
    def clean(self,value):
        """ Overriding it for that purpose"""
        
        if not value :
            raise forms.ValidationError("Bir port degeri girmeniz gerekir")
        
	    value=value.strip()
        #stands for single port and port-port
        port_pattern=re.compile(r"(^\d{1,5}$)|(^\d{1,5}-\d{1,5}$)")
        result=re.match(port_pattern,value)
        
        if not result: 
            raise forms.ValidationError("Port degeri formata uygun degil")
        
        if result.group(1):
            if not FireUtils.is_valid_port(result.group(1)):
                raise forms.ValidationError("Port degeri formata uygun degil")
            
            
        elif result.group(2):
            ports=result.group(2).split('-')
            
            if not FireUtils.is_valid_port(ports[0]):
                raise forms.ValidationError("Port degeri formata uygun degil")
            
            if not FireUtils.is_valid_port(ports[1]):
                raise forms.ValidationError("Port degeri formata uygun degil")
            
            
            if not int(ports[0]) < int(ports[1]): 
                raise forms.ValidationError("Port araligi uygun degil mi?")
            
        return value #it is valid ok man

#The ip validator    
###############################################################################################################
port_secenek=(
            ('a','hepsi'),
            ('r','port-aralik'),
            ('s','tek-port'),
            ('c','birkac'),
            )

s_port=re.compile(r"(^\d{1,5}$)")
r_port=re.compile(r"(^\d{1,5}-\d{1,5}$)")

class PortMultiField(forms.MultiValueField):
    """ Port form for Udp and Tcp rulez and validation"""
    
    def __init__(self,*args,**kwargs):
        """ The constructor part"""
        fields=(forms.ChoiceField(choices=port_secenek),
                forms.CharField(max_length=25),
                forms.BooleanField(required=False))
                
        super(PortMultiField,self).__init__(fields,*args,**kwargs)
        
#data={'kaynak_port_0':'a','kaynak_port_1':'0','kaynak_port_2':False}
#data={'kaynak_port_0':'r','kaynak_port_1':'10-12','kaynak_port_2':False}
#data={'kaynak_port_0':'c','kaynak_port_1':'12,23,44,55,66,77','kaynak_port_2':False}    
    def compress(self,data_list):
        """ The validation part"""
        
        if not data_list:
            raise forms.ValidationError("Bir port degeri girmeniz gerekir!")
        
        data_list[1]=data_list[1].strip()
        
        #if all chosen
        if data_list[0]=='a':
            if data_list[1]!='0':
                raise forms.ValidationError("Gecersiz hepsi degeri")
            
        
        #if it is a range in that case ...
        elif data_list[0]=='r':
            res=re.match(r_port,data_list[1])
            
            if not res:
                raise forms.ValidationError("Uygun olmayan Port araligi")
            
            
            ports=data_list[1].split('-')
            
            if not FireUtils.is_valid_port(ports[0]):
                raise forms.ValidationError("Port degeri formata uygun degil")
            
            if not FireUtils.is_valid_port(ports[1]):
                raise forms.ValidationError("Port degeri formata uygun degil")
            
            
            if not int(ports[0]) < int(ports[1]): 
                raise forms.ValidationError("Port araligi uygun degil mi?")
            
        
        elif data_list[0]=='s':
            res=re.match(s_port,data_list[1])
            
            if not res:
                raise forms.ValidationError("Uygun olmayan Port")
            
            if not FireUtils.is_valid_port(data_list[1]):
                raise forms.ValidationError("Port degeri formata uygun degil")
        
        #if it is a comma separated list with ports
        elif data_list[0]=='c':
            port_list=data_list[1].split(',')
            print port_list
            #controler=1
            
            for i in port_list:
                res=re.match(s_port,i)
                
                if not res:
                    raise forms.ValidationError("Fromat port,port olmali (uygunsuz Port)")
                
                if not FireUtils.is_valid_port(i):
                    raise forms.ValidationError("Fromat port,port olmali (uygunsuz Port)")
                
        
        return data_list #get the list        


class PortWidget(forms.MultiWidget):
    """ Needed for the class above """
    
    def __init__(self,attrs=None):
        
        #bu kisimla javascript yazilinca degiscek
        
        js_func=None
        if attrs:
            
            if attrs.has_key('port'):
                if attrs['port']=='s':
                    js_func={"onchange":'port_degisti(document.getElementsByName(\"kaynak_port_0\"),document.getElementsByName(\"kaynak_port_1\"))'}
                
                if attrs['port']=='d':
                    js_func={"onchange":'port_degisti(document.getElementsByName(\"hedef_port_0\"),document.getElementsByName(\"hedef_port_1\"))'}
                
                del attrs['port']
        
        if not js_func:
             the_js=attrs
             
        else:
            the_js=js_func
                    
        widgets=(forms.Select(attrs=js_func,choices=port_secenek),
                 forms.TextInput(attrs=attrs),
                 forms.CheckboxInput(attrs))
        
        super(PortWidget,self).__init__(widgets,attrs)
        
    
    def decompress(self,value):
        
        if value:
            
            return [value[0],value[1],value[2]]
        
        return [None,None,None]



###############################################################################################################
ip_secenek=(
            ('a','hepsi'),
            ('r','ip-aralik'),
            ('s','tek-ip'),
            ('n','ip-mask'),
            )

single_ip='(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}'
s_ip=re.compile(r'^%s$'%(single_ip))
r_ip=re.compile(r'^%s-%s$'%(single_ip,single_ip))
n_ip=re.compile(r'^%s/\d{1,2}$'%(single_ip))

class IpDropField(forms.MultiValueField):
    
    def __init__(self,*args,**kwargs):
        """ The constructor part"""
        fields=(forms.ChoiceField(label="Sec",choices=ip_secenek),
                forms.CharField(max_length=31,label="Ip:"),
                forms.BooleanField(label="!",required=False))
                
        super(IpDropField,self).__init__(fields,*args,**kwargs)
        
    
    def compress(self,data_list):
        """ The validation part"""
        
        if not data_list:
            raise forms.ValidationError("Bir ip degeri girmeniz gerekir!")
        
        #if it is a range
        if data_list[0]=='r':
            res=re.match(r_ip, data_list[1])
            
            if not res:
                raise forms.ValidationError("Gecersiz Ip Aralik")
            
            values=data_list[1].split('-')
            
            kucuk=values[0].strip().split('.')
            buyuk=values[1].strip().split('.')
            
            print kucuk
            print buyuk
            
            valid_man=False
            
            if len(kucuk)!=len(buyuk):
                raise forms.ValidationError("Ip araligi uygun degil")
                
            count_me=0
            for ip in kucuk :
                print "karsilastirilanlar :",int(ip)," ve :",int(buyuk[count_me])
                
                if int(ip)>int(buyuk[count_me]):
                    raise forms.ValidationError("Ip araligi uygun degil")
                elif int(ip)<int(buyuk[count_me]):
                    valid_man=True
                    break
                
                count_me=count_me +1
            
            if not valid_man:
                if int(kucuk[len(kucuk)-1]) ==  int(buyuk[len(buyuk)-1]):
                    raise forms.ValidationError("Ip araligi uygun degil")
            
            #if not values[0]<values[1]:
                #raise forms.ValidationError("Ip araligi uygun degil")
    
        
        elif data_list[0]=='s':
            res=re.match(s_ip, data_list[1])
        #some validation stuff here
            
            if not res:
                raise forms.ValidationError("Gecersiz Ip")
            
        elif data_list[0]=='n':
            res=re.match(n_ip, data_list[1])
        #some validation stuff here
            
            if not res:
                raise forms.ValidationError("Gecersiz Ip-Netmask")
            
            values=data_list[1].split('/')
            #print values
            if not int(values[1])>7 and int(values[1])<32:
                raise forms.ValidationError("Subnet degeri uygun degil")
            
        elif data_list[0]=='a':
            if data_list[1]!='0.0.0.0/0':
                raise forms.ValidationError("Gecersiz hepsi secenegi")
            
            
        return data_list
        


class IpDropWidget(forms.MultiWidget):
    """ Needed for the class above """
    
    def __init__(self,attrs=None):
        js_func=None
        if attrs:
            
            if attrs.has_key('ip'):
                if attrs['ip']=='s':
                    js_func={"onchange":'ip_degisti(document.getElementsByName(\"kaynak_ip_0\"),document.getElementsByName(\"kaynak_ip_1\"))'}
                
                if attrs['ip']=='d':
                    js_func={"onchange":'ip_degisti(document.getElementsByName(\"hedef_ip_0\"),document.getElementsByName(\"hedef_ip_1\"))'}
                
                del attrs['ip']
        
        if not js_func:
             the_js=attrs
             
        else:
            the_js=js_func
                    
        widgets=(forms.Select(attrs=js_func,choices=ip_secenek),
                 forms.TextInput(attrs=attrs),
                 forms.CheckboxInput(attrs))
        
        super(IpDropWidget,self).__init__(widgets,attrs)
        
    
    def decompress(self,value):
        
        if value:
            
            return [value[0],value[1],value[2]]
        
        return [None,None,None]
######################################################################################################

#load_secenek=FireUtils.get_loaded_rules()

class IpLoadField(forms.MultiValueField):
    """ We neeed a drop down list and a checkbox for that one"""
    def __init__(self,*args,**kwargs):
        """ The constructor part"""
        fields=(forms.ChoiceField(label="Sira"),
                forms.BooleanField(label="Yukle",initial=False,required=False))
                
        super(IpLoadField,self).__init__(fields,*args,**kwargs)
    
    
    def compress(self,data_list):
        """ The validation part"""
        
        if not data_list:
            raise forms.ValidationError("Yanlis secim oldu")
        
        
        return data_list
    

class IpLoadWidget(forms.MultiWidget):
    """ Needed for the class above """
    
    def __init__(self,attrs=None):
        widgets=(forms.Select(attrs=attrs),
                 forms.CheckboxInput(attrs))
        
        super(IpLoadWidget,self).__init__(widgets,attrs)
        
    
    def decompress(self,value):
        
        if value:
            
            return [value[0],value[1]]
        
        return [None,None]
#################################################################################################

class FlagField(forms.MultipleChoiceField):
    
    def __init__(self,*args,**kwargs):
        """ Calling the upper function"""
        super(FlagField,self).__init__(*args,**kwargs)
    
    def clean(self,value):
        """ Test one for multi selection"""
        
        if self.required and not value:
            raise ValidationError(ugettext(u'Bos birakilamaz'))
        elif not self.required and not value:
            return []
        if not isinstance(value, (list, tuple)):
            raise ValidationError(ugettext(u'Liste alir'))
        new_value = [val for val in value]
        # Validate that each value in the value list is in self.choices.
        print "The new value is :",new_value
        return new_value
    
re_plim=re.compile(r'^(\d+):(\d+)$')
#data={'p_limit':'111:10'}
class PaketLimitField(forms.CharField):
    """ Contrlling and supplying the format"""
    
    def __init__(self,*args,**kwargs):
        """ Calling the upper function"""
        super(PaketLimitField,self).__init__(*args,**kwargs)
    
    def clean (self,value):
        """ Test for the fomat man"""
        super(PaketLimitField,self).clean(value)
        
        if self.required and not value:
            raise forms.ValidationError(u'Paket limit Bos birakilamaz')
        
        elif not self.required and not value:
            return "0"
        
        value=value.strip()
        
        res=re.match(re_plim,value)
        if not res:
            raise forms.ValidationError(u'Paket limit paket:paket olmali')
        
        #split the values please
        bol=value.split(':')
        
        if not int(bol[0]) <= int(bol[1]):
            raise forms.ValidationError(u'Paket limit paket<=paket olmali')
        
        #the succesfull integration here
        return value

re_mac=re.compile(r'^([A-E]|[0-9]){2}:([A-E]|[0-9]){2}:([A-E]|[0-9]){2}:([A-E]|[0-9]){2}:([A-E]|[0-9]){2}:([A-E]|[0-9]){2}$')    
class MacField(forms.RegexField):
    """ That field handles the mac adress formating"""
    
    def __init__(self, max_length=None, min_length=None,*args, **kwargs):
        """ The constructor"""
        super(MacField,self).__init__(re_mac, max_length, min_length, 
                                         error_message="Girilen MAC Uygun Degil", *args, **kwargs)
                                         

class MyChainField(forms.CharField):
    """ It is needed for some initial values"""
    def __init__(self,*args,**kwargs):
        """ Calling the upper function"""
        super(MyChainField,self).__init__(*args,**kwargs)
        
    
    def clean (self,value):
        """Look at it """
        
        pat= re.compile(r'^(\w)([\w\-_]*)(\w)$')
        res= re.match(pat,value)
        
        if not res:
            raise forms.ValidationError(u'İzin verilmeyen karakter kullandınız !')
            
        if value in ['INPUT','OUTPUT','FORWARD']:
            raise forms.ValidationError(u'İzin verilmeyen kelime kullandınız!')
            
        return value
